home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / DCLAP 6d / dclap6d / DClap / DApplication.cpp < prev    next >
Text File  |  1996-07-05  |  33KB  |  1,354 lines

  1. // DApplication.cp
  2.  
  3.  
  4. #include "DClap.h"
  5. #include "DFindDlog.h"
  6.  
  7.  
  8. #if 0
  9. // Skeleton for application is
  10.  
  11. extern "C" Int2 Main (void)
  12. {
  13.   DMyApplication* myapp = new DMyApplication();
  14.   myapp->IApplication("App Name");
  15.   myapp->Run();
  16.   return 0;
  17. }
  18.  
  19. #endif
  20.  
  21.  
  22. DApplication* gApplication = NULL;        // the current application object
  23.  
  24. char* DApplication::kName=  NULL;
  25. char* DApplication::kVersion= NULL;
  26. char* DApplication::kHelpfolder = "Help";
  27. Nlm_RecT DApplication::fgAppWinRect;
  28.  
  29. extern "C" Nlm_Char        gProgramName[PATH_MAX];// from vibwndws.c
  30.  
  31.                     
  32. class DNoteWindow : public DWindow 
  33. {
  34. public:    
  35.     DNoteWindow(const char* message) :
  36.         DWindow( 0, NULL, DWindow::fixed, -5, -5, -50, -20, NULL)
  37.     {    
  38.     DNotePanel* note= new DNotePanel(0, this, message, 0, 0, Nlm_systemFont, justcenter);
  39.     }
  40.  
  41. };
  42.  
  43.  
  44.  
  45.  
  46.  
  47. class DWindowChoiceDialog : public DWindow 
  48. {
  49. public:
  50.     DListBox * fListBox;
  51.     short             fChoice;
  52.     DList      * fList;
  53.     
  54.     DWindowChoiceDialog();
  55.     void Open();
  56.     void OkayAction();
  57.     DWindow* Result();
  58. };
  59.  
  60.  
  61. DWindowChoiceDialog::DWindowChoiceDialog() :
  62.         DWindow( 0, NULL, DWindow::fixed, -10, -10, -50, -20, "Window list", kDontFreeOnClose),
  63.         fChoice(-1),
  64.         fList(NULL),
  65.         fListBox(NULL)
  66. {    
  67.     fList= gWindowManager->GetWindowList();
  68. }
  69.  
  70. void DWindowChoiceDialog::Open()
  71. {
  72.         // NOTE: this window is in window list !!
  73.     DPrompt* pr= new DPrompt(0, this, "Select a window");         
  74.     DListBox* lb= new DListBox(0, this, 20, 5, false);
  75.     fListBox= lb;
  76.     lb->SetResize( DView::relsuper, DView::relsuper);
  77.     lb->StartAppending();
  78.             
  79.     if (fList) {
  80.         char    title[256];
  81.         long i, n= fList->GetSize();
  82.         for (i= n-1; i>=0; i--) {
  83.             DWindow* win= (DWindow*) fList->At(i);
  84.             if (win != this) 
  85.             {
  86.                 win->GetTitle(title,256);
  87.                 lb->Append( title);
  88.                 }
  89.             }
  90.          }
  91.     lb->DoneAppending();
  92.     lb->SetValue(1); // doesn't seem active on DListBox display
  93.     
  94.     this->AddOkayCancelButtons();    
  95.     DWindow::Open();
  96. }
  97.  
  98. void DWindowChoiceDialog::OkayAction() 
  99.     //fChoice= fListBox->GetValue() - 1;  
  100.         //min GetValue==1, win fChoices == 0..GetSize-2, skip topwin = this
  101.     fChoice= (fList->GetSize() - 1) - (fListBox->GetValue() - 1);   
  102. }
  103.     
  104. DWindow* DWindowChoiceDialog::Result() 
  105.     if (fChoice<0) return NULL;
  106.     else return (DWindow*) fList->At(fChoice); 
  107. }
  108.     
  109.  
  110. // CLASS DAppWin
  111. class DAppWin : public DWindow
  112. {
  113. public:
  114.     DAppWin(long id, DTaskMaster* itsSuperior, WindowStyles style,
  115.                     short width = -5, short height = -5, short left = -50, short top = -20, 
  116.                     char* title = NULL, Nlm_Boolean freeOnClose= kFreeOnClose)
  117.         : DWindow( id, itsSuperior, style, width, height, left, top,
  118.                         title, freeOnClose)
  119.     { }
  120.     virtual void MakeGlobalsCurrent();
  121.     virtual void Close();
  122.     virtual void ResizeWin();
  123. };
  124.  
  125. void DAppWin::MakeGlobalsCurrent()
  126. {
  127.     ViewRect( fViewrect);  
  128.     if (!Nlm_EmptyRect(&fViewrect)) DApplication::fgAppWinRect= fViewrect;  
  129. }
  130.  
  131. void DAppWin::Close()
  132. {
  133.     MakeGlobalsCurrent();
  134.     DWindow::Close();
  135. }
  136.  
  137. void DAppWin::ResizeWin()
  138. {
  139.     DWindow::ResizeWin();
  140.     MakeGlobalsCurrent();
  141. }
  142.  
  143.  
  144.  
  145.  
  146.  
  147.  
  148. // CLASS DApplication
  149.  
  150. DApplication::DApplication() :
  151.     DTaskMaster(cAppl)
  152. {
  153.     fDone= false;    
  154.     fDidOpenStartDoc= false;    
  155.     fAppID= NULL;
  156.     fAppWindow= NULL;  
  157.     fPathname= NULL;
  158.     fShortname= NULL;
  159.     fAboutLine= NULL;
  160.     fFileSuffix= NULL;
  161.     fAcceptableFileTypes= NULL;
  162.     gApplication= this;
  163.         // default file types
  164.     fFileSuffix = ".txt";
  165.     fAcceptableFileTypes= "TEXT";
  166. }
  167.  
  168.  
  169.  
  170. void DApplication::IApplication(const char* theAppName)
  171. {
  172.     //xdebug("DApplication::IApplication");
  173.     DClapGlobals* initglobals = new DClapGlobals();
  174.     gCursor->watch();  
  175.     
  176.     if (kName) StrNCpy( gProgramName, kName, PATH_MAX); // for vibwndws.c
  177.     fPathname = StrDup( gFileManager->GetProgramPath());
  178.     if (theAppName) 
  179.         fShortname= StrDup( theAppName);
  180.     else if (kName) 
  181.         fShortname= StrDup( kName);
  182.     else {
  183.         fShortname= StrDup( gFileManager->FilenameFromPath(fPathname));   
  184.         char * suf= (char*)gFileManager->FileSuffix(fShortname);
  185.         if (suf) *suf= 0; // we don't want no steenking suffix here
  186.         }
  187.         
  188.     char buf[512];
  189.     sprintf( buf, "About %s...", Shortname()); 
  190.     fAboutLine= StrDup(buf);
  191.      
  192.     char *tid= DFileManager::TempFilenameonly();
  193.     if (StrNCmp(tid, "tmp", 3)) tid += 2;
  194.     fAppID= StrDup(tid);
  195.     //fAppID[0]= 'D'; //??
  196.     
  197. #ifndef WIN_MAC
  198.     if (!fAppWindow) {
  199.             // Non-Mac apps need an fAppWindow to put any application menus into 
  200.             // eventually want user pref for main wind rect...
  201.     short width= 450, height = 60;
  202.       Nlm_LoadRect( &fgAppWinRect, 0, 0, width, height);
  203.       char* srect = gApplication->GetPref( "fgAppWinRect", "windows", "0 0 450 60");
  204.         if (srect) {
  205.             sscanf( srect, "%hd%hd%hd%hd", &fgAppWinRect.left, &fgAppWinRect.top, 
  206.                                                 &fgAppWinRect.right, &fgAppWinRect.bottom);
  207.             width = MAX( 40, fgAppWinRect.right - fgAppWinRect.left); 
  208.             height= MAX( 60, fgAppWinRect.bottom - fgAppWinRect.top);   
  209.             MemFree(srect);
  210.             }
  211.         fAppWindow= new DAppWin(cAppW, this, DWindow::document, 
  212.                 width, height, fgAppWinRect.left, fgAppWinRect.top, 
  213.                 (char*)Shortname());
  214.         gWindowManager->SetAppWindow(fAppWindow);
  215.         //fAppWindow->Open(); //<<bad here -- main event loop
  216.         }
  217. #endif
  218.     
  219.     if (!gIconList) gIconList = new DIconList(); //<< do in DIconList.cpp as global init.
  220.   gIconList->ReadAppIcons();
  221.  
  222.     this->InitSpecialEvents();
  223.     this->InstallDefaultPrefs(); // do before calling any GetPref, after ShortName set
  224.     DFindDialog::InitFindDialog();
  225.     
  226.         // read some user prefs
  227.     gTextFontName= this->GetPref( "gTextFontName", "fonts", gTextFontName);
  228.     gTextFontSize= this->GetPrefVal( "gTextFontSize", "fonts", "12");
  229.     gTextTabStops= this->GetPrefVal( "gTextTabStops", "fonts", "4");
  230.     gTextFont         = Nlm_GetFont( gTextFontName, gTextFontSize, false, false, false, NULL);
  231.     if (!gTextFont) gTextFont= Nlm_programFont;
  232.     gItalicTextFont= Nlm_GetFont( gTextFontName, gTextFontSize, false, true, false, NULL);
  233.     if (!gItalicTextFont) gItalicTextFont= Nlm_programFont;
  234.     gBoldTextFont= Nlm_GetFont( gTextFontName, gTextFontSize, true, false, false, NULL);
  235.     if (!gBoldTextFont) gBoldTextFont= Nlm_programFont;
  236.     gUlineTextFont= Nlm_GetFont( gTextFontName, gTextFontSize, false, false, true, NULL);
  237.     if (!gUlineTextFont) gUlineTextFont= Nlm_programFont;
  238.   
  239.     DCluster::SetFont(Nlm_programFont);  
  240.  
  241.     this->SetUpMenus();
  242.     this->UpdateMenus(); // !! need to have this called in task loop somewhere !!
  243.     
  244.     //if (gOpenStartDocs) 
  245.     //OpenStartDocs();
  246.  
  247.  
  248. DApplication::~DApplication()
  249. {
  250.     if (gIconList) gIconList->suicide();
  251.     if (fAboutLine) MemFree( fAboutLine);
  252.     if (fShortname) MemFree( fShortname);
  253.     if (fPathname) MemFree( fPathname);
  254.     gApplication= NULL;
  255. }  
  256.  
  257.  
  258.  
  259. const char*    DApplication::Pathname(void)
  260. {
  261.     return    fPathname;
  262. }
  263.  
  264. const char*    DApplication::Shortname(void)
  265. {
  266.     static char buf[256];
  267.     StrNCpy(buf, fShortname, 256); // having problems w/ someone mangling this string !
  268.     return buf;
  269. }
  270.  
  271.  
  272.  
  273.  
  274. #ifdef WIN_MAC
  275. #ifndef __APPLEEVENTS__
  276.     // undef some conflicts b/n Types.h && NlmTypes
  277. #undef Handle
  278. #include <AppleEvents.h>
  279. #include <Strings.h>
  280. #endif
  281.  
  282. // ?!? 68k mac calls to here now fail --  
  283. // !! REQUIRES 'pascal' function call settings for Mac68K callbacks !
  284. #define CALLBACKFORM pascal
  285. //#define CALLBACKFORM extern "C"
  286.  
  287. #else
  288. #define CALLBACKFORM
  289. #endif
  290.  
  291. #ifdef WIN_MOTIF
  292.  
  293. #ifdef OS_UNIX_OSF1
  294. #undef _OSF_SOURCE
  295. #undef _POSIX_4SOURCE
  296. #define _ANSI_C_SOURCE
  297. #endif
  298.  
  299. #include <signal.h>
  300. #if defined(OS_UNIX_SUN) || defined(OS_UNIX_IRIX) || defined(OS_UNIX_LINUX)
  301. #include <sys/wait.h>
  302. #else
  303. #include <wait.h>
  304. #endif
  305.  
  306. extern int           statargc;
  307. extern char          **statargv;
  308. #endif
  309.  
  310.  
  311. // === AppleEvent Numbers ===
  312.  
  313. enum {
  314.                                         // Required Suite
  315. ae_OpenApp            = 1001,
  316. ae_OpenDoc            = 1002,
  317. ae_PrintDoc            = 1003,
  318. ae_Quit                = 1004,
  319.  
  320.                                         // Core Suite
  321. ae_Clone            = 2001,
  322. ae_Close            = 2002,
  323. ae_CountElements    = 2003,
  324. ae_CreateElement    = 2004,
  325. ae_Delete            = 2005,
  326. ae_DoObjectsExist    = 2006,
  327. ae_GetClassInfo        = 2007,
  328. ae_GetData            = 2008,
  329. ae_GetDataSize        = 2009,
  330. ae_GetEventInfo        = 2010,
  331. ae_Move                = 2011,
  332. ae_Open                = 1002,        // Same as ae_OpenDoc
  333. ae_Print            = 1003,        // Same as ae_PrintDoc
  334. ae_Save                = 2012,
  335. ae_SetData            = 2013,
  336.                                         // Miscellaneous Standards
  337. ae_ApplicationDied    = 3001,
  338. ae_BeginTransaction    = 3002,
  339. ae_Copy                = 3003,
  340. ae_CreatePublisher    = 3004,
  341. ae_Cut                = 3005,
  342. ae_DoScript            = 3006,
  343. ae_EditGraphic        = 3007,
  344. ae_EndTransaction    = 3008,
  345. ae_ImageGraphic        = 3009,
  346. ae_IsUniform        = 3010,
  347. ae_MakeObjVisible    = 3011,
  348. ae_Paste            = 3012,
  349. ae_Redo                = 3013,
  350. ae_Revert            = 3014,
  351. ae_TransactionTerm    = 3015,
  352. ae_Undo                = 3016,
  353. ae_Select            = 3017
  354. };
  355.  
  356.  
  357.  
  358. #ifdef WIN_MAC
  359.  
  360. static AEDescList    gAEDocList;
  361. static long gAEndoc, gAEidoc;
  362.  
  363. static Boolean SetAFileEvent( long inEvent, long outReply)
  364. {                    
  365.     AppleEvent    *aeEvent, *aeReply;
  366.     short                err;
  367.     
  368.     gAEndoc = gAEidoc = 0;
  369.     if (!inEvent) return false;
  370.     aeEvent = (AppleEvent*) inEvent;
  371.     //aeReply = (AppleEvent*) outReply;
  372.     err= AEGetParamDesc( aeEvent, keyDirectObject, typeAEList, &gAEDocList);
  373.     if (err) return false;
  374.     err= AECountItems( &gAEDocList, &gAEndoc);
  375.     return (err == 0);
  376. }
  377.  
  378. static void ClearAFileEvent()
  379. {                    
  380.     if (gAEndoc) {
  381.         (void) AEDisposeDesc( &gAEDocList);
  382.         gAEndoc= 0;
  383.         }
  384. }
  385.  
  386. static const char* GetNextAEFile()
  387. {                    
  388.     short                err;
  389.     AEKeyword        keywd;
  390.     DescType        returnedType;
  391.     FSSpec            aFileSpec;
  392.     Size                actualSize;
  393.     
  394.     if (gAEidoc < gAEndoc) {
  395.         gAEidoc++;
  396.         err= AEGetNthPtr( &gAEDocList, gAEidoc, typeFSS, &keywd, &returnedType,
  397.                                             (void*)&aFileSpec, sizeof(aFileSpec), &actualSize);
  398.         if (err) return NULL; 
  399. #ifdef COMP_THINKC
  400.         PtoCstr ((StringPtr) aFileSpec.name);
  401. #else
  402.         p2cstr((StringPtr) aFileSpec.name);
  403. #endif
  404.         return MacDirIDtoName( aFileSpec.vRefNum, aFileSpec.parID,
  405.                                                          (char*) aFileSpec.name);
  406.         }
  407.     else
  408.         return NULL;
  409. }
  410. #endif
  411.  
  412.  
  413. static Boolean gDidOpenStartDoc = false;
  414.  
  415. static void HandleFileEvent(long inEvent, long outReply, short tasknum)
  416. {
  417. #ifdef WIN_MAC
  418.     if (::SetAFileEvent( inEvent, outReply)) {
  419.         const char* path;
  420.         do {
  421.             path= ::GetNextAEFile();
  422.             if (path) {
  423.                 //gApplication->OpenDocument( (char*) path);
  424.                 DTask* filetask= 
  425.                   gApplication->newTask( tasknum, DTask::kMenu, (long)path);
  426.                 gApplication->DoMenuTask( tasknum, filetask);
  427.                 delete filetask;
  428.                 gApplication->fDidOpenStartDoc= true;
  429.                 }
  430.         } while (path);
  431.         ::ClearAFileEvent();
  432.         }
  433. #endif
  434.  
  435. #ifdef WIN_MOTIF
  436.     if (statargc > 1 
  437.    && !gDidOpenStartDoc) { 
  438.   //! gApplication->fDidOpenStartDoc) 
  439.         const char* path;
  440.         for (long i=1; i<statargc; i++) {
  441.             path= statargv[i];
  442.             if (path) {
  443.                 //gApplication->OpenDocument( (char*) path);
  444.                 DTask* filetask= 
  445.                   gApplication->newTask( tasknum, DTask::kMenu, (long)path);
  446.                 gApplication->DoMenuTask( tasknum, filetask);
  447.                 delete filetask;
  448.                 gApplication->fDidOpenStartDoc= true;
  449.                 }
  450.             } 
  451.         }
  452. #endif
  453. }
  454.  
  455.  
  456.  
  457. Boolean  DApplication::GotStartDocs()
  458. {
  459.     return fDidOpenStartDoc;
  460. }
  461.  
  462. Boolean DApplication::OpenStartDocs()
  463. {
  464.     gDidOpenStartDoc= fDidOpenStartDoc;
  465.     HandleSpecialEvent( 0, 0, ae_OpenDoc);
  466.     return fDidOpenStartDoc;
  467. }
  468.  
  469. #ifdef COMP_CWI
  470. static short int HandleSpecialEvent( long inEvent, long outReply, long inNumber)
  471. #else
  472. CALLBACKFORM short HandleSpecialEvent( long inEvent, long outReply, long inNumber)
  473. #endif
  474. {
  475.     short tasknum;
  476.     
  477.     switch (inNumber) {
  478.     
  479.         case ae_ApplicationDied:
  480.             (void) DChildAppManager::BuryDeadChildApp( inEvent);
  481.             break;
  482.             
  483.         case ae_Quit:
  484.             gApplication->Quit();
  485.             break;
  486.  
  487.         case ae_OpenApp:
  488.             //StartUp();
  489.             break;
  490.             
  491.         case ae_PrintDoc:
  492.             tasknum= DApplication::kPrintAFile;
  493.             goto caseOpenDoc;
  494.  
  495.         case ae_OpenDoc:
  496.             tasknum= DApplication::kOpenAFile;
  497.         caseOpenDoc:        
  498.             ::HandleFileEvent(inEvent, outReply, tasknum);
  499.             break;
  500.             
  501.         case ae_Copy:
  502.         case ae_Cut:
  503.         case ae_Paste:
  504.         case ae_Redo:
  505.         case ae_Undo:
  506.         default:
  507.             //DSomeone::HandleAppleEvent( inAppleEvent, outAEReply, outResult, inNumber);
  508.             break;
  509.         }
  510.  
  511.     return 0;
  512. }
  513.  
  514.  
  515. #ifdef WIN_MAC
  516. CALLBACKFORM short HandleChildDiedEvent( long inEvent, long outReply, long inNumber)
  517. {
  518.     return ::HandleSpecialEvent( inEvent, outReply, ae_ApplicationDied);
  519. }
  520. #endif
  521.  
  522. #ifdef WIN_MOTIF
  523. static void HandleChildDiedEvent(int signo)
  524. {
  525.     long     pid;
  526.     int        status;
  527.     //pid= wait( &status);
  528.     do {
  529.          pid= waitpid(-1, &status, WNOHANG|WUNTRACED);
  530.          // note: if child exits w/ error, exit(!0), pid == -1 !
  531.         if (pid>0) ::HandleSpecialEvent( pid, 0, ae_ApplicationDied); 
  532.     } while (pid>0);
  533. }
  534. #endif
  535.  
  536.  
  537. short DApplication::HandleSpecialEvent( long inEvent, long outReply, long inNumber)
  538. {
  539.     return ::HandleSpecialEvent(inEvent, outReply, inNumber);
  540. }
  541.  
  542.  
  543. void DApplication::InitSpecialEvents()
  544. {
  545.     short err;
  546. #ifdef WIN_MAC
  547.  
  548.     // problems w/ "aevt-oapp" call bombing on 68k mac but not ppc mac
  549.     
  550. #define aeproccall(x) NewAEEventHandlerProc(x)
  551. //#define aeproccall(x) ((AEEventHandlerUPP)(x))
  552.  
  553.     err= ::AEInstallEventHandler( kCoreEventClass, kAEOpenApplication,
  554.                                 aeproccall(::HandleSpecialEvent), 
  555.                                 //aeproccall(DApplication::HandleSpecialEvent), 
  556.                                 ae_OpenApp, false);
  557.     err= ::AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, 
  558.                                 aeproccall(::HandleSpecialEvent), 
  559.                                 //aeproccall(DApplication::HandleSpecialEvent), 
  560.                                 ae_Quit, false);
  561.  
  562.     err= ::AEInstallEventHandler( kCoreEventClass, kAEApplicationDied, 
  563.                                 aeproccall(::HandleChildDiedEvent), 
  564.                                 //aeproccall(DApplication::HandleSpecialEvent), 
  565.                                 ae_ApplicationDied, false);
  566.                                 
  567.     err = ::AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
  568.                                 aeproccall(::HandleSpecialEvent), 
  569.                                 //aeproccall(DApplication::HandleSpecialEvent), 
  570.                                 ae_OpenDoc, false);
  571.     err = ::AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments,
  572.                                 aeproccall(::HandleSpecialEvent), 
  573.                                 //aeproccall(DApplication::HandleSpecialEvent), 
  574.                                 ae_PrintDoc, false);
  575.  
  576. #endif
  577.  
  578. #ifdef WIN_MOTIF
  579.     // install signals to trap ?? childDied events at least
  580.     //err= sighold( SIGCHLD);
  581. #ifndef OS_UNIX_IRIX
  582.         // need to figure out IRIX format for this
  583.      signal( SIGCHLD, HandleChildDiedEvent); 
  584. #endif
  585. #endif
  586. }
  587.  
  588.  
  589.  
  590. Boolean DApplication::InstallDefaultPrefs(const char* defaultSuffix, const char* appName)
  591. {
  592.     Boolean foundprefs, didinstall= false;
  593.     char  *cp, defaultPrefs[512];
  594.     
  595.         // locate any program default preference file
  596.     if (!appName) appName= Shortname();
  597.  
  598.     StrNCpy(defaultPrefs, (char*)appName, 512);
  599.     cp= (char*)gFileManager->FileSuffix(defaultPrefs); if (cp) *cp= 0;
  600.     StrNCat(defaultPrefs, (char*)defaultSuffix, 512);
  601.     foundprefs= gFileManager->FileExists(defaultPrefs);
  602.     if (!foundprefs) {
  603.         const char* appPath = gFileManager->GetProgramPath();  
  604.         appPath= gFileManager->PathOnlyFromPath( appPath);
  605.         StrNCpy(defaultPrefs, (char*)appPath, 512);
  606.         StrNCat(defaultPrefs, (char*)appName, 512);
  607.         cp= (char*)gFileManager->FileSuffix(defaultPrefs); if (cp) *cp= 0;
  608.         StrNCat(defaultPrefs, (char*)defaultSuffix, 512);
  609.         foundprefs= gFileManager->FileExists(defaultPrefs);
  610.         }
  611.     
  612.     if (foundprefs) {
  613.         short     iline, nlines = 0;
  614.         char    **linelist;
  615.         char    * cp, * line = NULL, * section = NULL, * varname = NULL, * params = NULL;
  616.         long         curver= 0, defver= 0;
  617.          
  618.         curver= this->GetPrefVal("version","general",NULL);
  619.         linelist= gPrefManager->GetPrefFileLines( defaultPrefs, nlines);
  620.  
  621.             // 1st check quickly if defaultPrefs has anything newer than user prefs
  622.             // if not, exit silently, else put up notice window....
  623.         for (iline= 0; iline<nlines; iline++) {
  624.             line= linelist[iline];
  625.             if (*line == '[') { // sect name 
  626.                 cp= StrStr(line,"[version=");
  627.                 if (cp) defver= atol(cp+9);
  628.                 if (defver > curver) break;
  629.                 }
  630.             }
  631.         if (defver <= curver) {
  632.             for (iline= 0; iline<nlines; iline++) {
  633.                 line= linelist[iline];
  634.                 MemFree(line);
  635.                 }
  636.             MemFree(linelist);
  637.             return false;    
  638.             }
  639.             
  640.         Nlm_MonitorPtr progress= Nlm_MonitorIntNew("Installing new preferences...", 0, nlines);
  641.                 // ^^^ incorporate Nlm_Monitor into a DCLAP class
  642.         gCursor->watch();
  643.         for (iline= 0; iline<nlines; iline++) {
  644.             if (Nlm_MonitorIntValue(progress, iline)) ;
  645.             line= linelist[iline];
  646.             if (line) {
  647.                 if (*line == '[') { // sect name 
  648.                     cp= StrStr(line,"[version=");
  649.                     if (cp)  
  650.                         defver= atol(cp+9);
  651.                     else {
  652.                         if (section) MemFree(section);
  653.                         section= StrDup(line+1);
  654.                         }
  655.                     }
  656.                 else {
  657.                     params= StrChr(line, '=');
  658.                     if (params) { *params++= 0; if (!*params) params= NULL; }
  659.                     varname= line;
  660.                     if (defver > curver) {
  661.                         this->SetPref( params, varname, section);
  662.                         }
  663.                     }
  664.                 MemFree(line);
  665.                 }
  666.             }
  667.         MemFree(linelist);
  668.         this->SetPref(defver, "version","general");
  669.         didinstall= true;
  670.         Nlm_MonitorFree(progress);        
  671.         }
  672.      return didinstall;
  673. }
  674.  
  675.  
  676.  
  677.  
  678. char*    DApplication::GetPref(char* type, char* section, char* defaultvalue)
  679. {
  680.     return gPrefManager->GetAppPref( type, section, (char*)Shortname(), defaultvalue);
  681. }
  682.  
  683. long    DApplication::GetPrefVal(char* type, char* section, char* defaultvalue)
  684. {
  685.     long val= 0;
  686.     char* sval= gPrefManager->GetAppPref( type, section, (char*)Shortname(), defaultvalue);
  687.     if (sval) {
  688.         val= atol(sval);
  689.         MemFree(sval);
  690.         }
  691.     return val;
  692. }
  693.  
  694. char*    DApplication::GetPrefSection(char* section, ulong& sectlen, char* defaultvalue)
  695. {
  696.     return gPrefManager->GetAppPrefSection(section, sectlen, (char*)Shortname(), defaultvalue);
  697. }
  698.  
  699.  
  700. Boolean DApplication::SetPref(char* prefvalue, char* type, char* section)
  701. {
  702.     return gPrefManager->SetAppPref(prefvalue, type, section, (char*)Shortname());
  703. }
  704.  
  705. Boolean DApplication::SetPref(long prefvalue, char* type, char* section)
  706. {
  707.     char    snum[256];
  708.     sprintf(snum, "%d", prefvalue);
  709.     return gPrefManager->SetAppPref(snum, type, section, (char*)Shortname());
  710. }
  711.  
  712.  
  713. char*    DApplication::ConvertStdFilePath(char* pathname)
  714. {
  715.     char     *path, *atcolon, *name, *newpath;
  716.     
  717.     pathname= StrDup( pathname);
  718.     atcolon= StrChr(pathname, ':');
  719.     if (atcolon) {
  720.         name= atcolon+1;
  721.         *atcolon= 0;
  722.         path= this->GetPref( pathname, "paths", NULL);
  723.             // GetPref always returns nonNULL path
  724.         if (path && *path != '\0') {
  725. defaultpath:
  726.             DFileManager::UnixToLocalPath(path);
  727.             if (DFileManager::IsRelativePath(path)) {
  728.                 const char* appPath= DFileManager::PathOnlyFromPath( fPathname);
  729.                 newpath= StrDup( DFileManager::BuildPath( appPath, path, name)); 
  730.                 }
  731.             else
  732.                 newpath= StrDup( DFileManager::BuildPath( path, NULL, name)); 
  733.             MemFree( pathname);
  734.             MemFree( path);
  735.             pathname= newpath;
  736.             }
  737.         else if (StrICmp( pathname, "temp")==0) {
  738.             path= DFileManager::TempFolder();
  739.             newpath= StrDup( DFileManager::BuildPath( path, NULL, name)); 
  740.             MemFree( pathname);
  741.             pathname= newpath;
  742.             }
  743. #ifdef WIN_MAC
  744.         else {
  745.             *atcolon= ':';
  746.             }
  747. #else
  748.         else if (path)
  749.             goto defaultpath;
  750.         else {
  751.             // return full pathname !?
  752.             // MemMove(pathname, name, StrLen(name)+1);
  753.             }
  754. #endif
  755.         }
  756.     return pathname;
  757. }
  758.  
  759. char*    DApplication::GetFilePref(char* type, char* section, char* defaultvalue)
  760. {
  761.     char * pathname, *newpath;
  762.  
  763.     pathname = this->GetPref( type, section, defaultvalue);
  764.     newpath = ConvertStdFilePath( pathname);
  765.     MemFree( pathname);
  766.     return newpath;
  767. }
  768.  
  769.  
  770.  
  771.  
  772.  
  773.  
  774. #ifdef WIN_MOTIF
  775. extern void TaskCentralIdleEvent()
  776. {
  777.     gTaskCentral->NextTask();
  778. }
  779. #endif
  780.  
  781. void    DApplication::Run(void)
  782. {
  783.     if (fAppWindow)  fAppWindow->Open();
  784.     if (gClipboardMgr) gClipboardMgr->Launch();     
  785.  
  786.     gCursor->arrow();  
  787. #ifdef WIN_MOTIF
  788.   Nlm_Metronome( TaskCentralIdleEvent);
  789. #endif
  790.     this->MainEventLoop();
  791.     gCursor->arrow();
  792. }
  793.  
  794. void DApplication::MainEventLoop(void)
  795. {
  796.     while (!fDone) this->ProcessTasks();
  797. }
  798.  
  799. void DApplication::ProcessTasks(void)
  800. {
  801.     Nlm_ProcessEventOrIdle();
  802.     Nlm_RemoveDyingWindows();
  803.     gTaskCentral->NextTask();
  804. }
  805.  
  806. Boolean    DApplication::EventsAvail() 
  807.     return Nlm_EventAvail();
  808. }
  809.  
  810. void    DApplication::FlushEvents() 
  811.     Nlm_FlushEvents();
  812. }
  813.  
  814.  
  815. void DApplication::Quit()
  816. {
  817.     fDone= true;
  818.     if (gWindowManager) delete gWindowManager; gWindowManager= NULL;
  819.     // ?? ^^ is this okay, we got one bomb on a DWindow call after Quit & WinMgr == NULL
  820.  
  821.     if (!Nlm_EmptyRect(&fgAppWinRect)) {
  822.         char  srect[128];
  823.         sprintf( srect, "%d %d %d %d", fgAppWinRect.left, fgAppWinRect.top, 
  824.                                                         fgAppWinRect.right, fgAppWinRect.bottom);
  825.         gApplication->SetPref( srect, "fgAppWinRect", "windows");
  826.         }
  827.  
  828.   Nlm_QuitProgram (); // this justs sets a local vibrant global, in ProcessEvents(), which we don't see
  829. }
  830.  
  831. void    DApplication::SetAppMenuWindow(DWindow* itsWindow)
  832. {
  833.     fAppWindow= itsWindow;
  834. }
  835.  
  836.  
  837. void    DApplication::OpenDocument(char* pathname)
  838. {
  839.     DFile *afile= new DFile( pathname, "r");
  840.     OpenDocument( afile);
  841.     delete afile; // ???
  842. }
  843.  
  844. void    DApplication::OpenDocument(DFile* aFile)
  845. {
  846.     // default OpenDoc is to use Vibrant's text display
  847.     if (aFile && aFile->Exists()) {
  848.         Nlm_ParData  paratabs = {false, false, false, false, true, 0, 0}; // tabs==tabs
  849.         Nlm_ColData* coldata= NULL;
  850.  
  851.         gCursor->watch();
  852.         aFile->CloseFile(); // ShowFile manages this..
  853.         char* shortname= (char*)aFile->GetShortname();
  854.         DWindow* win= new DWindow(0, this, DWindow::document, -1, -1, -10, -10, shortname);
  855.         DTextDocPanel* td= new DTextDocPanel(0, win, 500, 300);
  856.  
  857.         td->SetSlateBorder( false);
  858.         td->SetResize( DView::matchsuper, DView::relsuper);
  859.         //td->SetTabs( gTextTabStops);
  860.         
  861.         const char* fullname= aFile->GetName();
  862. #if 0
  863.         td->ShowFile( (char*)fullname, gTextFont);
  864. #else
  865.         td->ShowFileFancy( (char*)fullname, ¶tabs, coldata, gTextFont, gTextTabStops);
  866. #endif
  867.         
  868.         win->Open();
  869.         td->SizeToSuperview( win, true, false); // this needs to adjust for if view has scrollbar !
  870.         gCursor->arrow();
  871.         }
  872. }
  873.  
  874.  
  875. Boolean    DApplication::ChooseFile(DFile*& openedFile, char* filesuffix, char* acceptableTypeIDs)
  876. {
  877.     DFile* aFile;
  878.     //if (openedFile) delete openedFile; //??
  879.     openedFile= NULL;
  880.     char* name= (char*) gFileManager->GetInputFileName( filesuffix, acceptableTypeIDs); 
  881.     if (name) {
  882.         aFile= new DFile( name, "r");
  883.         if (aFile->Exists()) {
  884.             openedFile= aFile;
  885.             return true;
  886.             }
  887.         else {
  888.             delete aFile;
  889.             return false;
  890.             }
  891.         }
  892.     else
  893.         return false;
  894. }
  895.  
  896.  
  897.  
  898. Boolean DApplication::DoMenuTask(long tasknum, DTask* theTask)
  899. {
  900.     DWindow* win;
  901.     
  902.     switch (tasknum) {
  903.  
  904.         case DAppleMenu::kAboutMenuItem: 
  905.             // ^^this is likely handled by DAppleMenu object
  906.         case kAbout:
  907.             this->DoAboutBox();
  908.             return true;
  909.  
  910.         case kHelp:
  911.             this->DoHelp();
  912.             return true;
  913.             
  914.         case kNew:
  915.             Message(MSG_OK,"DApplication::New not ready.");
  916.             //this->CreateDocument();
  917.             return true;
  918.         
  919.         case kPrintAFile:    
  920.         case kOpenAFile:
  921.             if (theTask)  
  922.                 this->OpenDocument( (char*)theTask->fExtra);
  923.             return true;
  924.             
  925.         case kOpen:
  926.             {
  927.             DFile* aFile = NULL;
  928.             if (this->ChooseFile( aFile, fFileSuffix, fAcceptableFileTypes)) 
  929.                 this->OpenDocument( aFile);
  930.             }
  931.             return true;
  932.             
  933.         case kClose: 
  934.             win= gWindowManager->CurrentWindow();
  935.             if (win) win->CloseAndFree(); // test win for doc needing saving ??
  936.             return true;
  937.                             
  938.         case kSave:
  939.         case kSaveAs:
  940.         case kSaveACopy:
  941.             win= gWindowManager->CurrentWindow();
  942.             if (win && win->fSaveHandler) {
  943.                 const char* name;
  944.                 char  namestore[256], *defname = NULL;
  945.                 Boolean changewinname= false;
  946.                 
  947.                 if (tasknum == kSave)
  948.                     defname= win->GetFilename(namestore,sizeof(namestore));
  949.                 if (!defname) 
  950.                     defname= win->GetTitle(namestore,sizeof(namestore));
  951.                 if (!defname || !*defname || StrCmp(defname,DFileManager::kUntitled)==0) 
  952.                     tasknum= kSaveAs;  
  953.                 if (tasknum == kSave)
  954.                     name= defname;
  955.                 else {
  956.                     name= gFileManager->GetOutputFileName(defname);
  957.                     changewinname= (tasknum == kSaveAs);
  958.                     }
  959.                 if (name && *name) {
  960.                     DFile* myFile = new DFile(name, "w");
  961.                     if (myFile) {
  962.                         myFile->OpenFile();
  963.                         win->SaveDoc(myFile); 
  964.                         if (changewinname) {
  965.                           win->SetFilename((char*) name);
  966.                           win->SetTitle((char*)DFileManager::FilenameFromPath(name));
  967.                           }
  968.                         myFile->CloseFile();
  969.                         delete myFile;
  970.                         }
  971.                     }
  972.                 }
  973.             else 
  974.                 Message(MSG_OK,"DApplication::Save not ready.");
  975.             return true;
  976.  
  977.         case kFindAgain:
  978.             win= gWindowManager->CurrentWindow();
  979.             if (win && win->fFindDlog) 
  980.                 win->fFindDlog->FindAgain(); 
  981.             else
  982.                 Message(MSG_OK,"DApplication::FindAgain not available.");
  983.             return true;
  984.             
  985.         case kFind:
  986.             win= gWindowManager->CurrentWindow();
  987.             if (win && win->fFindDlog) {
  988.                 if ( win->fFindDlog->PoseModally() ) ;
  989.                 }
  990.             else
  991.                 Message(MSG_OK,"DApplication::Find not available.");
  992.             return true;
  993.             
  994.         case kPrint:
  995.             win= gWindowManager->CurrentWindow();
  996.             if (win && win->fPrintHandler) 
  997.                 win->PrintDoc();
  998.             else
  999.                 Message(MSG_OK,"DApplication::Print not ready.");
  1000.             return true;
  1001.  
  1002.         case kQuit:
  1003.             this->Quit(); // this should be a task added to end of task queue...??
  1004.             return true;
  1005.             
  1006.         case kPrevWindow:
  1007.             gWindowManager->BringToFront();
  1008.             return true;
  1009.         case kNextWindow:
  1010.             gWindowManager->SendToBack();
  1011.             return true;
  1012.             
  1013.         case kChooseWindow:
  1014. #ifndef BOBS_WIN_MAC                        
  1015.           {
  1016.             DWindowChoiceDialog* dlg= new DWindowChoiceDialog();
  1017.             if ( dlg->PoseModally() ) {
  1018.                 DWindow* win = dlg->Result();
  1019.                 if (win && win != dlg) win->Select();
  1020.                 }
  1021.             delete dlg;
  1022.             }
  1023. #else
  1024. #endif
  1025.             return true;
  1026.  
  1027.         case kUndo:
  1028.             if (gLastCommand) gLastCommand->UndoRedo();
  1029.             return true;
  1030.  
  1031.         case kDeleteDeadWindow:
  1032.             {
  1033.             DView* windowCarcass= (DView*) theTask->fExtra;
  1034.             if (windowCarcass) delete windowCarcass;
  1035.             }
  1036.             return true;
  1037.  
  1038.         default: 
  1039.             return DTaskMaster::DoMenuTask(tasknum, theTask);
  1040.         }
  1041. }
  1042.  
  1043.  
  1044.  
  1045. Boolean DApplication::IsMyAction(DTaskMaster* action)
  1046. {
  1047.     switch(action->Id()) {
  1048.  
  1049.         case DAppleMenu::kAboutMenuItem:
  1050.         case kAbout:
  1051.         case kHelp:
  1052.         case kNew:
  1053.         case kOpen:
  1054.         case kClose:
  1055.         case kSaveAs:
  1056.         case kSaveACopy:
  1057.         case kSave:
  1058.         case kPrint:
  1059.         case kQuit:
  1060.         case kPrevWindow:
  1061.         case kNextWindow:
  1062.         case kChooseWindow:
  1063.         case kFind:
  1064.         case kFindAgain:
  1065.         case kUndo:
  1066.             return DoMenuTask(action->Id(), NULL);
  1067.  
  1068.         case kCut:
  1069.         case kCopy:
  1070.         case kPaste:
  1071.         case kClear:
  1072.         case kSelectAll:
  1073.             {
  1074.                     // looks like Vibrant doesn't currently support a system clipboard for
  1075.                     // copy/paste of text (& other objects) between applications...
  1076.             static Boolean inrecurse = false;
  1077.             DWindow* win = gWindowManager->CurrentWindow();
  1078.             DDialogText* dtext= gWindowManager->CurrentDialogText();
  1079.             if (inrecurse) return true;
  1080.             inrecurse= true;
  1081.             if (dtext && win && win->HasEditText()) {
  1082.                 if (win != dtext->GetWindow()) dtext = win->fEditText;
  1083.                     // ^^ if this is true, we can't tell which of multiple texts may be
  1084.                     // the intended target ... CurrentDialogText() is supposed to track user text.
  1085.                 if (dtext->IsMyAction(action))  goto doneEditCmd;
  1086.                 }
  1087.             if (win && win->IsMyAction(action)) goto doneEditCmd;
  1088.             Message(MSG_OK,"Application::Edits not ready.");
  1089.     doneEditCmd:
  1090.             inrecurse= false;
  1091.             return true;
  1092.             }
  1093.             
  1094.         case kShowClipboard:
  1095.             gClipboardMgr->DoMenuTask( action->Id(), NULL);
  1096.             return true;
  1097.             
  1098.         case cOKAY:
  1099.         case cCANC:
  1100.             {
  1101.             DButton* but= (DButton*) action;
  1102.             DWindow* win;
  1103.             if ( but && ((win= but->GetWindow()) != NULL) ) {
  1104.                 if (action->Id() == cOKAY) {
  1105.                     // do Okay close handling...
  1106.                     }
  1107.                 win->CloseAndFree();
  1108.                 }
  1109.             }
  1110.             return true;
  1111.  
  1112.         default:
  1113.             return DTaskMaster::IsMyAction(action);
  1114.         }
  1115. }
  1116.  
  1117. DMenu* DApplication::NewMenu(long id, char* title)
  1118. {
  1119.     Nlm_WindoW nwind = (fAppWindow) ? (Nlm_WindoW)fAppWindow->GetNlmObject() : NULL;
  1120.     return new DPulldownMenu( id, this, nwind, title);
  1121. }
  1122.  
  1123.  
  1124. extern "C" void Nlm_SetupMenuBar();
  1125.  
  1126. void    DApplication::SetUpMenus(void)
  1127. {
  1128.     DMenu* aMenu = NULL;
  1129.     this->SetUpMenu(cFileMenu, aMenu);
  1130.     aMenu= NULL;
  1131.     this->SetUpMenu(cEditMenu, aMenu);
  1132.     aMenu= NULL;
  1133.     this->SetUpMenu(cWindowMenu, aMenu);
  1134.     this->SetUpMenu( 0, aMenu);
  1135. }
  1136.  
  1137. void DApplication::SetUpMenu(short menuId, DMenu*& aMenu) 
  1138. {
  1139.     // ?? either change menu objects to local/nonpointer, 
  1140.     // or suicide() them to remove all but DViewCentral owner
  1141.     
  1142.     if (menuId == cFileMenu) {
  1143. #ifdef WIN_MAC
  1144.         DAppleMenu* appleMenu = new DAppleMenu(this,fAboutLine);
  1145. #endif
  1146.         if (!aMenu) aMenu = this->NewMenu( cFileMenu, "File");
  1147. #ifndef WIN_MAC
  1148.         aMenu->AddItem(kAbout, fAboutLine);
  1149.         aMenu->AddSeparator();
  1150. #endif
  1151.         aMenu->AddItem(kNew,"New/N",false, true);
  1152.         aMenu->AddItem(kOpen,"Open/O",false, true);
  1153.         aMenu->AddSeparator();
  1154.         aMenu->AddItem(kClose,"Close/W",false, true);
  1155.         aMenu->AddItem(kSave,"Save/S",false, true);
  1156.         aMenu->AddItem(kSaveAs,"Save As...",false, true);
  1157.         aMenu->AddSeparator();
  1158.         aMenu->AddItem(kPrint,"Print",false, true);
  1159.         aMenu->AddItem(kHelp,"Help/H",false, true);
  1160.         aMenu->AddSeparator();
  1161.         aMenu->AddItem(kQuit,"Quit/Q",false, true);
  1162.         }
  1163.     
  1164.     else if (menuId == cEditMenu) {
  1165.         if (!aMenu) aMenu = this->NewMenu(cEditMenu, "Edit");
  1166.         aMenu->AddItem(kUndo,"Undo/Z",false, true);
  1167.         gViewCentral->DisableView(kUndo);  // don't know undo yet... :-(ouch)
  1168.         aMenu->AddSeparator();
  1169.         aMenu->AddItem(kCut,"Cut/X",false, true);
  1170.         aMenu->AddItem(kCopy,"Copy/C",false, true);
  1171.         aMenu->AddItem(kPaste,"Paste/V",false, true);
  1172.         aMenu->AddItem(kClear,"Clear",false, true);
  1173.         aMenu->AddItem(kSelectAll,"Select All/A",false, true);    
  1174.         aMenu->AddItem(kShowClipboard,"Show clipboard",false, true);
  1175.         gViewCentral->DisableView(DApplication::kShowClipboard);
  1176.         }
  1177.         
  1178.     else if (menuId == cWindowMenu) {
  1179.         if (!aMenu) aMenu= this->NewMenu(cWindowMenu, "Windows");
  1180.         aMenu->AddItem(kPrevWindow,"Prev/-",false, true); // == bring last win to front
  1181.         aMenu->AddItem(kNextWindow,"Next/+",false, true); // == send top win to last
  1182.         aMenu->AddItem(kChooseWindow,"Select...");  
  1183.         //aMenu->AddSeparator();
  1184.         //this->AddWindowListToMenu(menuId, aMenu); //gWindowManager->GetWindowList();
  1185.         }
  1186.         
  1187.     else if (menuId == 0) {
  1188.         Nlm_SetupMenuBar();
  1189.         }
  1190.  
  1191. }
  1192.  
  1193.  
  1194.  
  1195. #if NOT_READY
  1196.     
  1197. void DApplication::SetWindowMenu(Boolean activate)
  1198. {                  
  1199. #ifndef BOBS_WIN_MAC                        
  1200.                         // THIS IS NO GOOD ON XWIN, and on MSWIN
  1201.                         // Vibrant currently has no way of removing single menu items
  1202.                         // except for Mac.  Only option for others seems to be removal
  1203.                         // of entire (sub) menu, with no way to replace w/ a new menu
  1204.                         // in *same* position !!!
  1205. #else                        
  1206.    if (fWindowChoiceMenu) {
  1207.          short item= kViewDefault;
  1208.          fWindowChoiceMenu->Reset();  
  1209.          fWindowChoiceMenu->AddItem( item, "default");
  1210.          DList* wins= gWindowManager->GetWindowList();
  1211.          if (activate && wins) {
  1212.             long i, n= wins->GetSize();
  1213.             for (i= 0; i<n; i++) {
  1214.                 char *cp, title[256];
  1215.                 item++;
  1216.                 DWindow* win= (DWindow*) fList->At(i);
  1217.                 win->GetTitle(title,256);
  1218.                 cp= title; 
  1219.                 //while (cp= strchr(cp, '/')) *cp= '_';
  1220.                 fViewChoiceMenu->AddItem( item, smenu);
  1221.                 }
  1222.              }
  1223.      }
  1224. #endif
  1225. }
  1226.  
  1227. #endif
  1228.  
  1229.  
  1230.  
  1231.      
  1232. void DApplication::DoHelp()
  1233. {
  1234.     char filename[512];
  1235.     DFile* afile = new DFile();
  1236.     char* suf;
  1237.     
  1238.     char* apppath = (char*) gFileManager->GetProgramPath();  
  1239.     apppath= (char*) gFileManager->PathOnlyFromPath( apppath);
  1240.     apppath= (char*)gFileManager->BuildPath( apppath, kHelpfolder, (char*)Shortname());
  1241.     afile->Initialize(apppath,"r");
  1242.     if (!afile->Exists()) {
  1243.         StrNCpy(filename, (char*)Shortname(),490);
  1244.         StrCat(filename,".help");
  1245.         afile->Initialize(filename,"r");
  1246.         if (!afile->Exists()) {
  1247.             StrNCpy(filename, (char*)Pathname(),490);
  1248.             suf= (char*)gFileManager->FileSuffix(filename); if (suf) *suf= 0;
  1249.             StrCat(filename,".help");
  1250.             afile->Initialize(filename,"r");
  1251.             }
  1252.         }
  1253.     OpenHelp( afile);
  1254.     delete afile;
  1255. }
  1256.  
  1257.  
  1258.  
  1259. void DApplication::OpenHelp(const char* helpname)
  1260. {
  1261.     char* apppath = (char*) gFileManager->GetProgramPath();  
  1262.     apppath= (char*) gFileManager->PathOnlyFromPath( apppath);
  1263.     const char*    pathname= gFileManager->BuildPath( apppath, kHelpfolder, helpname);
  1264.     DFile* afile = new DFile(pathname,"r");
  1265.     OpenHelp(afile);
  1266.     delete afile;
  1267. }
  1268.  
  1269.  
  1270. void DApplication::OpenHelp(DFile* aFile)
  1271. {
  1272. #if 1
  1273.     if (!aFile || !aFile->Exists()) {
  1274.         const char * name;
  1275.         if (aFile) name= aFile->GetName(); else name= "noname";
  1276.         Message(MSG_OK,"Can't find help file '%s'",name);
  1277.         return;
  1278.         }
  1279.     this->OpenDocument( aFile); 
  1280. #else
  1281.     Nlm_ParData  paratabs = {false, false, false, false, true, 0, 0}; // tabs==tabs
  1282.     Nlm_ColData* coldata= NULL;
  1283.         
  1284.     if (!aFile->Exists()) {
  1285.         Message(MSG_OK,"Can't find help file '%s'",aFile->GetName());
  1286.         return;
  1287.         }
  1288.         
  1289.     gCursor->watch();
  1290.     aFile->CloseFile(); // make sure closed so ShowFile can open !?
  1291.     DWindow* win= new DWindow(cHelp, this, DWindow::document, -1, -1, -10, -10, 
  1292.                                         (char*) aFile->GetShortname());
  1293.     DTextDocPanel* td= new DTextDocPanel(0, win, 490, 300);
  1294.     td->SetSlateBorder( false);
  1295.     td->SetResize( DView::matchsuper, DView::relsuper);
  1296. #if 0
  1297.     td->ShowFile( (char*)aFile->GetName(), gTextFont);
  1298. #else
  1299.     td->ShowFileFancy( (char*)aFile->GetName(), ¶tabs, coldata, gTextFont, gTextTabStops);
  1300. #endif
  1301.     win->Open();
  1302.     td->SizeToSuperview( win, true, false);  
  1303.     gCursor->arrow();
  1304. #endif
  1305. }
  1306.  
  1307.  
  1308. void DApplication::DoAboutBox(void)
  1309. {
  1310.     DAboutBoxWindow* about = new DAboutBoxWindow; // make instance & it handles rest
  1311. }
  1312.  
  1313.     
  1314.  
  1315.  
  1316. void DApplication::UpdateMenus( void)
  1317. {
  1318.         // Is the frontmost window modal?
  1319.     
  1320.     gViewCentral->EnableView(DApplication::kQuit);
  1321.  
  1322.     //if (gInBackground) 
  1323.     {
  1324.         gViewCentral->EnableView(DApplication::kClose);
  1325.         //gViewCentral->EnableView(DApplication::kUndo);
  1326.         gViewCentral->EnableView(DApplication::kCut);
  1327.         gViewCentral->EnableView(DApplication::kCopy);
  1328.         gViewCentral->EnableView(DApplication::kPaste);
  1329.         gViewCentral->EnableView(DApplication::kClear);
  1330.     } 
  1331.  
  1332.     //if (!isModalWindow) 
  1333.     {
  1334.         gViewCentral->EnableView(DApplication::kNew);
  1335.         gViewCentral->EnableView(DApplication::kOpen);
  1336.     }
  1337.  
  1338.     gViewCentral->EnableView(DApplication::kPrevWindow);
  1339.     gViewCentral->EnableView(DApplication::kNextWindow);
  1340.     
  1341.     //Str63    undoStr;
  1342.     //GetIndString(undoStr, STRcommon, strUNDO);
  1343.     //gViewCentral->SetMenuText( DApplication::kUndo, undoStr);
  1344. }
  1345.  
  1346.  
  1347.  
  1348.  
  1349.